package com.sqeakecleanblog.mediaplayer.view
{
	import com.ghostmonk.events.PercentageEvent;
	import com.ghostmonk.events.audio.AudioEvent;
	import com.ghostmonk.events.video.*;
	import com.ghostmonk.media.SoundSpectrum;
	import com.ghostmonk.media.audio.MusicPlayer;
	import com.ghostmonk.media.video.VideoScreen;
	import com.ghostmonk.ui.*;
	import com.ghostmonk.ui.idecomposed.*;
	import com.sqeakecleanblog.mediaplayer.ApplicationFacade;
	import com.sqeakecleanblog.mediaplayer.components.*;
	import com.sqeakecleanblog.mediaplayer.components.media.*;
	import com.sqeakecleanblog.mediaplayer.events.*;
	import com.sqeakecleanblog.mediaplayer.model.structures.Playlist;
	
	import flash.events.*;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class MediaPlayerMediator extends Mediator
	{
		public static const NAME:String = "MediaPlayerMediator";
		public static const MEDIA_LOAD:String = "MediaLoad";
		
		private var _videoScreen:IMediaPlayer;
		private var _musicPlayer:IMediaPlayer;
		private var _currentPlayer:IMediaPlayer;
		
		private var _playList:Playlist;
		private var _currentTotalTime:Number;
		
		private var _controlPanel:MediaControls;
		
		private var _currentItem:int;
		
		public function get player():TVScreen
		{
			return viewComponent as TVScreen;
		}
		
		public function MediaPlayerMediator()
		{
			super(NAME);
		}
		
		override public function onRegister():void
		{
			var videoScreen:VideoScreen = new VideoScreen(true);
			var musicPlayer:MusicPlayer = new MusicPlayer();
			
			_videoScreen = new SqueakVideo(videoScreen);
			_musicPlayer = new SqueakAudio(new MusicPlayer());
			
			var soundSpectrum:SoundSpectrum = SoundSpectrumMediator(facade.retrieveMediator(SoundSpectrumMediator.NAME)).spectrum;
			viewComponent = new TVScreen(soundSpectrum, videoScreen);
			
			videoScreen.addEventListener(MetaInfoEvent.META_INFO_READY, onMetaInfoReady);
			musicPlayer.addEventListener(AudioEvent.ON_ID3, onID3);
			
			SqueakAudio(_musicPlayer).addEventListener(NetStreamEvent.STOP, playNextItem);
			SqueakVideo(_videoScreen).addEventListener(NetStreamEvent.STOP, playNextItem);
		}
		
		override public function listNotificationInterests():Array
		{
			return [
						ApplicationFacade.PLAYLIST_LOADED,
						ApplicationFacade.APP_INIT
					];
		}
		
		override public function handleNotification(notification:INotification):void
		{
			switch(notification.getName())
			{
				case ApplicationFacade.PLAYLIST_LOADED:
					
					_playList = notification.getBody() as Playlist;
					_currentItem = _playList.currentNode;
					break;
				case ApplicationFacade.APP_INIT:
					_controlPanel = facade.retrieveMediator(MediaControlsMediator.NAME).getViewComponent() as MediaControls;
					
					_controlPanel.addEventListener(VideoControlEvent.PAUSE, onStop);
					_controlPanel.addEventListener(VideoControlEvent.PLAY, onPlay);
					_controlPanel.addEventListener(ShuttleEvent.SHUTTLE, onShuttle);
					_controlPanel.addEventListener(PercentageEvent.CHANGE, onPercentChange);
					
					_controlPanel.addEventListener(PlaylistNavEvent.NEXT_PREVIOUS, onPlaylistNextPrevious);
					_controlPanel.addEventListener(PlaylistNavEvent.PLAYLIST_CHANGE, onPlaylistChange);
					break;
			}
		}
		
		private function onPlay(e:VideoControlEvent):void
		{
			_currentPlayer.play();
		}
		
		private function onStop(e:VideoControlEvent):void
		{
			_currentPlayer.pause();
		}
		
		private function onMetaInfoReady(e:MetaInfoEvent):void
		{
			_currentTotalTime = e.metaData.duration;
		}
		
		private function onID3(e:AudioEvent):void
		{
			
		}
		
		private function onVideoEnterFrame(e:Event):void
		{
			var playPercent:Number = _currentPlayer.time/_currentTotalTime;
			_controlPanel.timeChange(_currentPlayer.time, _currentPlayer.percentLoaded, playPercent); 
			if(_currentPlayer == _musicPlayer) _currentTotalTime = _musicPlayer.duration;
		}
		
		private function onPlaylistChange(e:PlaylistNavEvent):void
		{
			_currentItem = e.value;
			load();
		}
		
		private function onPlaylistNextPrevious(e:PlaylistNavEvent):void
		{
			_currentItem = getNextItem(e.value);
			load();
		}
		
		private function playNextItem(e:Event):void
		{
			_currentItem = getNextItem(1);
			load();
		}
		
		private function getNextItem(i:int):int
		{
			var node:int = _playList.currentNode + i;
			
			node = node == -1 ? _playList.length - 1 : node;
			node = node == _playList.length ? 0 : node;
			
			return node;
		}
		
		private function onShuttle(e:ShuttleEvent):void
		{
			var curTime:Number = _currentPlayer.time;
			_currentPlayer.seek(curTime + e.value);
		}
		
		private function onPercentChange(e:PercentageEvent):void
		{
			_currentPlayer.seek(_currentTotalTime*e.percent);
		}
		
		private function load():void
		{
			var targetURL:String = _playList.getItem(_currentItem).url; 
			if(_currentPlayer != null) _currentPlayer.remove();
			var type:String = targetURL.substr(targetURL.length - 3, 3);
			
			facade.sendNotification(MEDIA_LOAD, type=="mp3");
			
			if(type == "mp3")
				_controlPanel.disable();
			else
				_controlPanel.enable();
			
			_currentPlayer = type == "mp3" ? _musicPlayer : _videoScreen;
			_currentPlayer.load(targetURL);
			_controlPanel.addEventListener(Event.ENTER_FRAME, onVideoEnterFrame);
			_controlPanel.setView(_currentItem);
		}
		
	}
}